package cn.hyh;

import cn.hyh.models.BaseDatabase;
import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.BeanProcessor;
import org.apache.commons.dbutils.GenerousBeanProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.RowProcessor;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

/**
 * @param <T> 配置对象
 *            2020/7/29
 * @author hyh
 */
public class JdbcUtil<T extends BaseDatabase> {

    /**
     * 数据库配置
     */
    private final T config;

    public JdbcUtil(T config) throws ClassNotFoundException {
        this.config = config;
        Class.forName(config.getDriverClass());
    }

    /**
     * 获取数据库连接
     *
     * @return 连接实体
     * @throws SQLException 连接异常
     */
    public Connection getConnection() throws SQLException {
        return DriverManager.getConnection(config.getUrl(), config.getUsername(), config.getPassword());
    }

    /**
     * 返回结果只有一行一列的查询, 用于count统计等
     *
     * @param sql 查询语句
     * @return 结果对象, 可能为null
     * @throws SQLException 语句异常
     */
    public Object get(String sql) throws SQLException {
        Connection connection = getConnection();
        QueryRunner queryRunner = new QueryRunner();
        Object result = queryRunner.query(connection, sql, new ScalarHandler<>());
        connection.close();
        return result;
    }

    /**
     * 返回结果只有一行的查询, 如根据主键查询等
     *
     * @param sql    查询语句
     * @param oClass 返回结果实体类的class
     * @param params 查询条件
     * @param <O>    返回结果实体类
     * @return 结果实体
     * @throws Exception 语句异常
     */
    public <O> O get(String sql, Class<O> oClass, Object... params) throws Exception {
        Connection connection = getConnection();
        QueryRunner queryRunner = new QueryRunner();
        BeanProcessor beanProcessor = new GenerousBeanProcessor();
        RowProcessor rowProcessor = new BasicRowProcessor(beanProcessor);
        O result = queryRunner.query(connection, sql, new BeanHandler<>(oClass, rowProcessor), params);
        connection.close();
        return result;
    }

    /**
     * 列表查询
     *
     * @param sql    查询语句
     * @param oClass 返回结果实体类的class
     * @param params 查询条件
     * @param <O>    返回结果实体类
     * @return 结果实体数组
     * @throws SQLException 语句异常
     */
    public <O> List<O> list(String sql, Class<O> oClass, Object... params) throws SQLException {
        Connection connection = getConnection();
        QueryRunner queryRunner = new QueryRunner();
        BeanProcessor beanProcessor = new GenerousBeanProcessor();
        RowProcessor rowProcessor = new BasicRowProcessor(beanProcessor);
        List<O> result = queryRunner.query(connection, sql, new BeanListHandler<>(oClass, rowProcessor), params);
        connection.close();
        return result;
    }

    /**
     * 批量插入数据
     *
     * @param sql    插入语句
     * @param params 插入数据二维数组
     * @throws SQLException 语句异常
     */
    public void insert(String sql, Object[][] params) throws SQLException {
        Connection connection = getConnection();
        QueryRunner queryRunner = new QueryRunner();
        queryRunner.batch(connection, sql, params);
        connection.close();
    }

    /**
     * 更新
     *
     * @param sql    更新语句
     * @param params 更新内容
     * @throws SQLException 语句异常
     */
    public void update(String sql, Object... params) throws SQLException {
        Connection connection = getConnection();
        QueryRunner queryRunner = new QueryRunner();
        queryRunner.update(connection, sql, params);
        connection.close();
    }

}
